package pe.com.bbva.ge.persistencia.orm.hibernate;

import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.Serializable;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import pe.com.bbva.ge.domain.configuracion.Valor;
import pe.com.bbva.ge.persistencia.orm.CrudORM;
import pe.com.bbva.ge.persistencia.orm.hibernate.utileria.Busqueda;

@Repository
public class CrudORMHibernate extends BaseORMHibernate implements CrudORM {

	/**
	 * 
	 */
	private static final long serialVersionUID = 3215544455370306384L;
	
	@Autowired
	public CrudORMHibernate(SessionFactory sessionFactory) {
		super(sessionFactory);
		logger.trace("Creando Implementación GenericoORMHibernate");
		//setSessionFactory(sessionFactory);
	}

	@Override
	public <Entidad> Entidad obtener(Serializable id, Class<Entidad> clase) {
		return getHibernateTemplate().get(clase, id);
	}

	@Override
	public <Entidad> void modificar(Entidad entidad) {
		getHibernateTemplate().update(entidad);
		getHibernateTemplate().flush();
	}

	@Override
	public <Entidad> void crear(Entidad entidad) {
		getHibernateTemplate().persist(entidad);
	}

	@Override
	public <Entidad> void grabarTodos(List<Entidad> lista) {
		getHibernateTemplate().saveOrUpdateAll(lista);
	}

	@Override
	public <Entidad> void eliminar(Entidad entidad) {
		getHibernateTemplate().delete(entidad);
		getHibernateTemplate().flush();
	}

	@Override
	public <Entidad> void eliminarTodos(List<Entidad> lista) {
		getHibernateTemplate().deleteAll(lista);
	}

	@SuppressWarnings("unchecked")
	@Override
	public <Entidad> List<Entidad> obtenerTodos(Class<Entidad> clase) {
		return (getHibernateTemplate().find("from " + clase.getName() + " x"));
	}

	@SuppressWarnings("unchecked")
	@Override
	public <Entidad> long contar(Class<Entidad> clase) {
		List<Entidad> list = getHibernateTemplate().find(
				"select count(*) from " + clase.getName() + " x");
		Long count = (Long) list.get(0);
		return count.longValue();
	}

	@Override
	public <Entidad> List<Entidad> obtenerActivos(Class<Entidad> clase) {

		boolean tieneEstado = false;
		boolean estadoValor = false;
		
		PropertyDescriptor[] propertyDescriptors = null;
		try {
			propertyDescriptors = Introspector.getBeanInfo(clase).getPropertyDescriptors();
		} catch (IntrospectionException e) {
			e.printStackTrace();
		}
		
		for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
			tieneEstado = propertyDescriptor.getName().equals("estado");
			if(tieneEstado)
			{
				estadoValor = propertyDescriptor.getPropertyType() == Valor.class;
				break;
			}
		}
		Busqueda filtro = Busqueda.forClass(clase);
		if(tieneEstado)
		{
			String propertyName = StringUtils.EMPTY;
			if(estadoValor)
			{
				filtro.createAlias("estado", "e");
				propertyName = "e.codigo";
			}
			else
			{
				propertyName = "estado";
			}
			filtro.add(Restrictions.eq(propertyName, Valor.CODIGO.REGISTRO_ESTADO_ACTIVO));
		}
		
		return buscar(filtro);
	}

}
